package logic

import (
	"context"
	"errors"
	"gozeroStandalone/define"
	"gozeroStandalone/internal/model"
	"gozeroStandalone/internal/svc"
	"gozeroStandalone/internal/types"
	"gozeroStandalone/utils"
	"strings"

	"github.com/zeromicro/go-zero/core/logx"
	"github.com/zeromicro/go-zero/core/stores/sqlx"
)

/*
 +----------------------------------------------------------------------
 + Title        : OrderLogic
 + Author       : huwl
 + Version      : 1.0.0
 + Initial-Time : 2025-08-08
 + Last-time    : 这个文件最后修改的时间 + 修改人的名称
 + Desc         : 订单逻辑
 +----------------------------------------------------------------------
*/

type OrderLogic struct {
	BaseLogic
}

/**
 * 创建订单逻辑实例
 *
 * @param context.Context ctx ----------------------必传
 * @param *svc.ServiceContext svcCtx ---------------必传
 * @return *OrderLogic
 * @author huwl
 * @date 2025/10/24 12:54:03
 */
func NewOrderLogicInstance(ctx context.Context, svcCtx *svc.ServiceContext) *OrderLogic {
	return &OrderLogic{
		BaseLogic{
			Ctx:    ctx,
			SvcCtx: svcCtx,
			Logger: logx.WithContext(ctx),
		},
	}
}

/**
 * 购物车创建订单
 *
 * @param types.OrderCreateRequest params ----------必传
 * @return uint64, error
 * @author huwl
 * @date 2025/10/24 15:29:35
 */
func (logic *OrderLogic) CartCreateOrder(params types.OrderCreateRequest) (uint64, error) {
	if params.Platform <= 0 {
		return 0, errors.New("商城平台错误")
	}
	if params.Username == "" {
		return 0, errors.New("用户名不能为空")
	}
	if params.AddressId <= 0 {
		return 0, errors.New("收货地址Id错误")
	}

	return 0, nil
}

/**
 * 创建订单
 *
 * @param types.OrderCreateRequest params ----------必传
 * @return error
 * @author huwl
 * @date 2025/10/24 15:29:35
 */
func (logic *OrderLogic) GenerateOrder(params types.OrderCreateRequest) (uint64, error) {
	if params.GoodsSkuId <= 0 {
		return 0, errors.New("请选择商品规格选项")
	}
	if params.Platform <= 0 {
		return 0, errors.New("商城平台错误")
	}
	if params.Username == "" {
		return 0, errors.New("用户名不能为空")
	}
	if params.AddressId <= 0 {
		return 0, errors.New("收货地址Id错误")
	}
	if params.Num <= 0 {
		return 0, errors.New("请选择商品数量")
	}

	var oid int64
	err := logic.SvcCtx.OrderModel.Conn().TransactCtx(context.Background(), func(ctx context.Context, s sqlx.Session) error {
		var err error
		// 新增订单
		oid, err = logic.SvcCtx.OrderModel.InsertTx(ctx, s, model.MallOrder{
			Platform:   params.Platform,
			Uid:        2212,
			Username:   "多宝天君",
			Amount:     2,
			OrderMoney: 3400,
			PayMoney:   3400,
			CreateTime: types.Now(),
		})
		if err != nil {
			return err // 返回错误，事务会自动回滚
		}

		// 新增订单明细
		orderItems := []interface{}{
			model.MallOrderItem{
				Oid:           uint64(oid),
				GoodsId:       25,
				GoodsSkuId:    1179,
				GoodsName:     "肉色0d丝袜超薄款性感女隐形全透明薄款脚尖无痕",
				GoodsNum:      1,
				GoodsCoverUrl: "xxxxx.png",
				GoodsPrice:    1600,
				GoodsSkuText:  "浅肤色 均码",
				PayMoney:      1600,
			},
			model.MallOrderItem{
				Oid:           uint64(oid),
				GoodsId:       25,
				GoodsSkuId:    1181,
				GoodsName:     "肉色0d丝袜超薄款性感女隐形全透明薄款脚尖无痕",
				GoodsNum:      1,
				GoodsCoverUrl: "xxxxx.png",
				GoodsPrice:    1800,
				GoodsSkuText:  "裸肤色 均码",
				PayMoney:      1800,
			},
		}
		err = logic.SvcCtx.OrderItemModel.BatchInsertTx(ctx, s, orderItems)
		if err != nil {
			return err // 返回错误，事务会自动回滚
		}

		return nil
	})

	return uint64(oid), err
}

/**
 * 支付
 *
 * @param types.OrderPayRequest params -------------必传
 * @return error
 * @author huwl
 * @date 2025/10/24 15:29:35
 */
func (logic *OrderLogic) Pay(params types.OrderPayRequest) error {
	if params.Oid <= 0 {
		return errors.New("订单编号错误")
	}
	if params.PayChannel <= 0 {
		return errors.New("支付通道错误")
	}

	// 获取订单数据
	order, err := logic.SvcCtx.OrderModel.FindOne(logic.Ctx, int64(params.Oid))
	if err != nil {
		if strings.Contains(err.Error(), "no rows in result set") {
			return errors.New("订单信息错误")
		}
		return err
	}
	if order.Status != 0 {
		return errors.New("订单已取消/支付")
	}

	return logic.SvcCtx.OrderModel.Conn().TransactCtx(context.Background(), func(ctx context.Context, s sqlx.Session) error {
		// 更新订单状态
		err := logic.SvcCtx.OrderModel.EditByPrimaryKeyWithTx(ctx, s, map[string]interface{}{
			"pay_channel":      params.PayChannel,
			"pay_channel_note": params.PayChannelNote,
			"status":           1,
			"pay_time":         utils.GetDate(),
		}, params.Oid, "oid")
		if err != nil {
			return err // 返回错误，事务会自动回滚
		}

		// 更新订单明细状态
		err = logic.SvcCtx.OrderItemModel.EditByParamsWithTx(ctx, s, map[string]interface{}{
			"status": 1,
		}, map[string]interface{}{
			"oid": params.Oid,
		})
		if err != nil {
			return err // 返回错误，事务会自动回滚
		}

		return nil
	})
}

/**
 * 列表
 *
 * @param types.QueryOrderRequest params -----------必传
 * @param uint8 page -------------------------------必传
 * @param int8 pageSize ----------------------------必传
 * @return []*model.MallOrderValue, int64, error
 * @author huwl
 * @date 2025/10/14 12:54:03
 */
func (logic *OrderLogic) List(params types.QueryOrderRequest, page uint8, pageSize int8) ([]*model.MallOrderValue, int64, error) {
	data := map[string]interface{}{
		"o.is_invalid": 0,
	}

	if params.Oid > 0 {
		data["o.oid"] = params.Oid
	}
	if params.Oids != "" {
		data["o.oid IN (?)"] = utils.IntSplit(params.Oids, ",")
	}
	if params.Platform > 0 {
		data["o.platform"] = params.Platform
	}
	if params.Uid > 0 {
		data["o.uid"] = params.Uid
	}
	if params.Uids != "" {
		data["o.uid IN (?)"] = utils.IntSplit(params.Uids, ",")
	}
	if params.Username != "" {
		data["o.username"] = params.Username
	}
	if params.GoodsName != "" {
		data["o.goods_name"] = params.GoodsName
	}
	if params.PayChannel > 0 {
		data["o.pay_channel"] = params.PayChannel
	}
	if params.IsDelete != "all" {
		data["o.is_delete"] = params.IsDelete
	}
	if params.Status != "all" {
		data["o.status IN (?)"] = utils.IntSplit(params.Status, ",")
	}
	if params.StartCreateTime != "" {
		data["o.create_time >= ?"] = params.StartCreateTime + " 00:00:00"
	}
	if params.EndCreateTime != "" {
		data["o.create_time <= ?"] = params.EndCreateTime + " 23:59:59"
	}
	if params.SortField == "" {
		params.SortField = "o.oid"
	}
	if params.SortType == "" {
		params.SortType = "DESC"
	}

	// 获取数量
	total, err := logic.SvcCtx.OrderModel.GetListByTotal(logic.Ctx, data)
	if err != nil {
		return nil, 0, err
	}

	orderValues := []*model.MallOrderValue{}
	if total > 0 {
		// 获取订单数据
		orders := []*model.MallOrder{}
		err := logic.SvcCtx.OrderModel.GetListByParams(logic.Ctx, &orders, data, uint32(page), pageSize, params.SortField+" "+params.SortType)
		if err != nil {
			return nil, 0, err
		}

		// 组装订单编号
		oids := []int{}
		for _, order := range orders {
			oids = append(oids, int(order.Oid))

			// 获取支付渠道文本
			payChannelText := ""
			payChannel, ok := define.GetPayChannel(int(order.PayChannel))["value_txt"]
			if ok {
				payChannelText = payChannel.(string)
			}

			orderValues = append(orderValues, &model.MallOrderValue{
				Oid:                   order.Oid,
				Platform:              order.Platform,
				PlatformText:          define.GetPlatform(int(order.Platform))["value_txt"].(string),
				Uid:                   order.Uid,
				Username:              order.Username,
				Amount:                order.Amount,
				OrderMoney:            order.OrderMoney,
				ReduceMoney:           order.ReduceMoney,
				PayMoney:              order.PayMoney,
				OtherMoney:            order.OtherMoney,
				PayChannel:            order.PayChannel,
				PayChannelText:        payChannelText,
				PayChannelNote:        order.PayChannelNote,
				PayTime:               order.PayTime,
				CancelReason:          order.CancelReason,
				UnsubscribeServiceFee: order.UnsubscribeServiceFee,
				Note:                  order.Note,
				Status:                order.Status,
				StatusText:            define.GetOrderStatus(int(order.Status))["value_txt"].(string),
				IsDelete:              order.IsDelete,
				CreateTime:            order.CreateTime,
				UpdateTime:            order.UpdateTime,
			})
		}

		// 获取订单明细数据
		orderItems := []*model.MallOrderItem{}
		err = logic.SvcCtx.OrderItemModel.GetResultsByParams(logic.Ctx, &orderItems, map[string]interface{}{
			"oid IN (?)": oids,
		}, 1, -1, "id DESC")
		if err != nil {
			return nil, 0, err
		}

		// 组装订单明细数据
		for _, orderValue := range orderValues {
			for _, orderItem := range orderItems {
				if orderValue.Oid == orderItem.Oid {
					orderValue.OrderItems = append(orderValue.OrderItems, &model.MallOrderItem{
						Id:                    orderItem.Id,
						Oid:                   orderItem.Oid,
						GoodsId:               orderItem.GoodsId,
						GoodsSkuId:            orderItem.GoodsSkuId,
						GoodsName:             orderItem.GoodsName,
						GoodsCoverUrl:         orderItem.GoodsCoverUrl,
						GoodsNum:              orderItem.GoodsNum,
						GoodsPrice:            orderItem.GoodsPrice,
						GoodsSkuText:          orderItem.GoodsSkuText,
						PayMoney:              orderItem.PayMoney,
						OtherMoney:            orderItem.OtherMoney,
						UnsubscribeServiceFee: orderItem.UnsubscribeServiceFee,
						Note:                  orderItem.Note,
						Status:                orderItem.Status,
						UpdateTime:            orderItem.UpdateTime,
					})
				}
			}
		}
	}

	return orderValues, total, nil
}

/**
 * 详情
 *
 * @param uint64 oid -------------------------------必传
 * @return map[string]interface{}, error
 * @author huwl
 * @date 2025/10/14 12:54:03
 */
func (logic *OrderLogic) Detail(oid uint64) (map[string]interface{}, error) {
	if oid <= 0 {
		return nil, errors.New("订单编号错误")
	}

	// 获取订单数据
	order, err := logic.SvcCtx.OrderModel.FindOne(logic.Ctx, int64(oid))
	if err != nil {
		return nil, err
	}
	if order.IsInvalid == 1 {
		return nil, errors.New("订单信息错误")
	}

	// 获取订单明细数据
	orderItems := []*model.MallOrderItem{}
	err = logic.SvcCtx.OrderItemModel.GetResultsByParams(logic.Ctx, &orderItems, map[string]interface{}{
		"oid": oid,
	}, 1, -1, "id DESC")
	if err != nil {
		return nil, err
	}

	// 获取订单收货地址
	var orderDeliveryAddrData model.MallOrderDeliveryAddress
	err = logic.SvcCtx.OrderDeliveryAddressModel.Row(logic.Ctx, &orderDeliveryAddrData, map[string]interface{}{
		"oid": order.Oid,
	})
	if err != nil {
		if err == model.ErrNotFound {
			return nil, errors.New("收货地址信息错误")
		}

		return nil, err
	}

	// 获取订单快递
	var orderExpress model.MallOrderExpress
	logic.SvcCtx.OrderExpressModel.Row(logic.Ctx, &orderExpress, map[string]interface{}{
		"oid": order.Oid,
	})

	// 获取支付渠道文本
	payChannelText := ""
	payChannel, ok := define.GetPayChannel(int(order.PayChannel))["value_txt"]
	if ok {
		payChannelText = payChannel.(string)
	}

	// 组装数据
	result := map[string]interface{}{
		"order": model.MallOrderValue{
			Oid:                   order.Oid,
			Platform:              order.Platform,
			PlatformText:          define.GetPlatform(int(order.Platform))["value_txt"].(string),
			Uid:                   order.Uid,
			Username:              order.Username,
			Amount:                order.Amount,
			OrderMoney:            order.OrderMoney,
			ReduceMoney:           order.ReduceMoney,
			PayMoney:              order.PayMoney,
			OtherMoney:            order.OtherMoney,
			PayChannel:            order.PayChannel,
			PayChannelText:        payChannelText,
			PayChannelNote:        order.PayChannelNote,
			PayTime:               order.PayTime,
			CancelReason:          order.CancelReason,
			UnsubscribeServiceFee: order.UnsubscribeServiceFee,
			Note:                  order.Note,
			Status:                order.Status,
			StatusText:            define.GetOrderStatus(int(order.Status))["value_txt"].(string),
			IsDelete:              order.IsDelete,
			CreateTime:            order.CreateTime,
			UpdateTime:            order.UpdateTime,
			OrderItems:            orderItems,
		},
		"order_delivery_addr": orderDeliveryAddrData,
		"order_express":       nil,
	}

	if orderExpress.Id > 0 {
		result["order_express"] = orderExpress
	}

	return result, nil
}
